package com.frank.oj.util;

import cn.hutool.json.JSONUtil;
import com.frank.model.entity.problem.Problem;
import org.springframework.util.StringUtils;

import java.util.*;

public class JudgeUtils {

    @SuppressWarnings("All")
    public static HashMap<String, String> getProblemExtraFileMap(Problem problem, String type) {
        if ("user".equals(type)) {
            if (!StringUtils.isEmpty(problem.getUserExtraFile())) {
                return (HashMap<String, String>) JSONUtil.toBean(problem.getUserExtraFile(), Map.class);
            }
        } else if ("judge".equals(type)) {
            if (!StringUtils.isEmpty(problem.getJudgeExtraFile())) {
                return (HashMap<String, String>) JSONUtil.toBean(problem.getJudgeExtraFile(), Map.class);
            }
        }
        return null;
    }

    /**
     * 将命令行字符串转换为单独的参数列表。
     * 此方法专门处理包含空格和引号的命令行字符串，将它们分解为单独的单词或引用的字符串。
     *
     * @param toProcess 要转换的命令行字符串。可以是null或空字符串。
     * @return 一个列表，包含解析出的每个参数。如果输入是null或空，则返回空列表。
     * @throws RuntimeException 如果引号不平衡（即开始但未结束的引号）。
     */
    public static List<String> translateCommandline(String toProcess) {
        // 如果输入字符串非空，则进行处理
        if (toProcess != null && !toProcess.isEmpty()) {
            int state = 0; // 状态变量，用于跟踪当前解析的状态：0-正常，1-在单引号内，2-在双引号内
            StringTokenizer tok = new StringTokenizer(toProcess, "\"' ", true); // 分割字符串，考虑引号和空格
            List<String> result = new ArrayList<>(); // 存储解析结果
            StringBuilder current = new StringBuilder(); // 当前正在处理的token
            boolean lastTokenHasBeenQuoted = false; // 标记上一个token是否被引号引用

            // 循环处理所有tokens
            while (true) {
                // 循环处理当前token
                while (tok.hasMoreTokens()) {
                    String nextTok = tok.nextToken();
                    switch (state) {
                        // 在单引号内
                        case 1:
                            if ("'".equals(nextTok)) {
                                lastTokenHasBeenQuoted = true;
                                state = 0;
                            } else {
                                current.append(nextTok);
                            }
                            continue;
                        // 在双引号内
                        case 2:
                            if ("\"".equals(nextTok)) {
                                lastTokenHasBeenQuoted = true;
                                state = 0;
                            } else {
                                current.append(nextTok);
                            }
                            continue;
                    }

                    // 处理其他情况
                    if ("'".equals(nextTok)) {
                        state = 1;
                    } else if ("\"".equals(nextTok)) {
                        state = 2;
                    } else if (" ".equals(nextTok)) {
                        // 如果当前token被引号引用或非空，则添加到结果列表
                        if (lastTokenHasBeenQuoted || current.length() > 0) {
                            result.add(current.toString());
                            current.setLength(0);
                        }
                    } else {
                        current.append(nextTok);
                    }

                    lastTokenHasBeenQuoted = false;
                }

                // 如果最后一个token被引号引用或非空，则添加到结果列表
                if (lastTokenHasBeenQuoted || current.length() > 0) {
                    result.add(current.toString());
                }

                // 如果没有未结束的引号，则返回结果列表
                if (state != 1 && state != 2) {
                    return result;
                }

                // 如果有未结束的引号，则抛出异常
                throw new RuntimeException("unbalanced quotes in " + toProcess);
            }
        } else {
            // 如果输入字符串为空，则直接返回空列表
            return new ArrayList<>();
        }
    }

}